import call from './call.js'

const is = (tokens) => {
  return tokens.peek().type === 'keyword' && (
    tokens.peek().value === 'var' || tokens.peek().value === 'const'
  )
}

const parse = (tokens) => {
  const node = {
    type: 'VariableDeclaration',
    declarations: [],
    kind: tokens.peek().value
  }

  tokens.next()

  while (!tokens.eof()) {
    if (tokens.peek().type !== 'identifier') {
      tokens.croak(`Can't handle token: ${ tokens.peek().value }`)
    }

    const id = {
      type: 'Identifier',
      name: tokens.peek().value
    }

    tokens.next()

    if (tokens.peek().type !== 'operator' || tokens.peek().value !== ':') {
      tokens.croak(`Can't handle token: ${ tokens.peek().value }`)
    }

    tokens.next()

    if (tokens.peek().type !== 'keyword' || !/^(int|string)$/.test(tokens.peek().value)) {
      tokens.croak(`Can't handle token: ${ tokens.peek().value }`)
    }

    const init = {
      type: 'Literal',
      value: ''
    }

    const type = tokens.peek().value

    if (type === 'int') {
      init.value = 0
    } else if (type === 'string') {
      init.value = ''
    }

    tokens.next()

    if (tokens.peek().type !== 'operator' || tokens.peek().value !== '=') {
      tokens.croak(`Can't handle token: ${ tokens.peek().value }`)
    }

    tokens.next()

    if (tokens.peek().type !== 'number' && tokens.peek().type !== 'literal' && tokens.peek().type !== 'identifier') {
      tokens.croak(`Can't handle token: ${ tokens.peek().value }`)
    }

    const var_type = typeof tokens.peek().value

    if (tokens.peek().type === 'identifier') {
      const name = tokens.peek().value

      node.declarations.push({
        type: 'VariableDeclarator',
        id: id,
        init: {
          type: 'Identifier',
          name: name
        }
      })

      tokens.next()

      if (tokens.peek().type === 'punctuation' && tokens.peek().value === '(') {
        node.declarations.pop()
        node.declarations.push({
          type: 'VariableDeclarator',
          id: id,
          init: call.parse(tokens, name)
        })
      }

      break
    }

    if (type === 'int' && var_type !== 'number') {
      const got = var_type === 'string' ? `"${ tokens.peek().value }"` : tokens.peek().value
      tokens.croak(`Need a number, but got: ${ got }`)
    }

    if (type === 'string' && var_type !== 'string') {
      tokens.croak(`Need a string, but got: ${ tokens.peek().value }`)
    }

    init.type = type
    init.value = tokens.peek().value

    tokens.next()

    node.declarations.push({
      type: 'VariableDeclarator',
      id,
      init
    })

    if (!tokens.eof() && tokens.peek().type === ',') {
      tokens.next()
    } else {
      break
    }
  }

  return node
}

export default {
  is,
  parse
}